//
#include <assert.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "cuImgRotation.cuh"
/*#define THREAD_NUM 256*/
bool InitCUDA(){

	int	count;

	cudaGetDeviceCount(&count) ;

	if ( count == 0)
	{
		fprintf(stderr, "There is no device.\n") ;

		return false;
	}

	int	 i;

	for ( i = 0 ;i < count ; i++)
	{
		cudaDeviceProp prop ;

		if ( cudaGetDeviceProperties(& prop ,i) == cudaSuccess)
		{
			if ( prop.major >= 1)
			{
				break;
			}
		}
	}
	if ( i == count)
	{
		fprintf(stderr ,"There is no device supporting CUDA1.x.\n");

		return false;
	}

	cudaSetDevice( i );

	return true;

}

__global__ void imageRotateBlock(unsigned char* inBuf, unsigned char* outBuf ,int imgHei, int imgWid , int outHei, int outWid ,float m_angle){

	int halfH = outHei/2;
	int halfW = outWid/2;

	int tid = threadIdx.x;
	int bid = blockIdx.x;
	float cosA = cosf(m_angle);
	float sinA = sinf(m_angle);
	for(int i = bid*THREAD_NUM+tid ;i < imgWid*imgHei; i+=THREAD_NUM*BLOCK_NUM){
// 	for (int i = tid; i < imgWid*imgHei;i+=THREAD_NUM)
// 	{
		int y0 = i/imgWid;
		int x0 = i-y0*imgWid;
		int x = x0-imgWid/2;
		int y = imgHei/2-y0;
		int xx = int(cosA*x-sinA*y+halfW);
		int yy = int(halfH-sinA*x-cosA*y);
		outBuf[xx+yy*outWid] = inBuf[i];
	}
}
__global__ void imageRotate(unsigned char* inBuf, unsigned char* outBuf ,int imgHei, int imgWid , int outHei, int outWid ,float m_angle){

	int halfH = outHei/2;
	int halfW = outWid/2;

	int tid = threadIdx.x;
	float cosA = cosf(m_angle);
	float sinA = sinf(m_angle);
	for (int i = tid; i < imgWid*imgHei;i+=THREAD_NUM)
	{
		int y0 = i/imgWid;
		int x0 = i-y0*imgWid;
		int x = x0-imgWid/2;
		int y = imgHei/2-y0;
		int xx = int(cosA*x-sinA*y+halfW);
		int yy = int(halfH-sinA*x-cosA*y);
		outBuf[xx+yy*outWid] = inBuf[i];
	}
}
 void	imgRotate(unsigned char* inBuf, unsigned char* outBuf ,int imgHei, int imgWid , int outHei, int outWid ,float m_angle)
{
	 
	 imageRotate<<<1,THREAD_NUM>>>(inBuf, outBuf ,imgHei, imgWid , 
		  outHei,  outWid , m_angle);
//	 imageRotateBlock<<<1,THREAD_NUM>>>(inBuf, outBuf ,imgHei, imgWid , outHei, outWid , m_angle);
}


// 	for ( int iband = 0; iband < nBands ;iband++)
// 	{
// 		inBuf = pImgData->getBandBuf(iband);
// 		for (int y = 0 ;y < imgHei ;y++)
// 		{
// 			for (int x = 0; x < imgWid; x++)
// 			{
// 				xx = x - imgWid/2;
// 				yy = imgHei/2 - y;
// 				int	xxx = int(cosA*xx-sinA*yy+halfW);
// 				int	yyy = int(halfH-sinA*xx-cosA*yy);
// 				outBuf[xxx+yyy*outWid] = inBuf[x+y*imgWid];
// 			}
// 
// 		}
//}